﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Willow.Extensions;
using Willow.IRepository;
using Willow.IService;

namespace Willow.Service
{
    public class BaseService<TEntity> : IService<TEntity> where TEntity : class
    {
        public IRepository<TEntity> Repository;
        public IUnitOfWork UnitOfWork;

        public BaseService(IUnitOfWork unitOfWork)
        {
            Repository = unitOfWork.GetStandardRepository<TEntity>();
            UnitOfWork = unitOfWork;
        }

        public BaseService(IRepository<TEntity> repository, IUnitOfWork unitOfWork)
        {
            Repository = repository;
            UnitOfWork = unitOfWork;
        }

        public TEntity FirstOrDefault(Expression<Func<TEntity, bool>> expression)
        {
            return Repository.FirstOrDefault(expression);
        }

        public List<TEntity> All()
        {
            return Repository.All().ToList();
        }

        public virtual List<TEntity> Filter(Expression<Func<TEntity, bool>> predicate)
        {
            return Repository.Filter(predicate).ToList();
        }

        public virtual List<TEntity> Filter(Expression<Func<TEntity, bool>> filter, out int total, int index = 0,
                                               int size = 50)
        {
            return Repository.Filter(filter, out total, index, size).ToList();
        }

        public virtual List<TEntity> Filter(Expression<Func<TEntity, bool>> filter, out int total, int index = 0,
                                               int size = 50, params PropertySortCondition[] sortConditions)
        {
            return Repository.Filter(filter, out total, index, size, sortConditions).ToList();
        }

        public virtual IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> predicate)
        {
            return Repository.Filter(predicate);
        }

        public virtual void Create(TEntity TObject)
        {
            Repository.Create(TObject);
        }

        public virtual void Delete(TEntity TObject)
        {
            Repository.Delete(TObject);            
        }

        public virtual void Update(TEntity TObject)
        {
            Repository.Update(TObject);
        }

        public virtual void Delete(Expression<Func<TEntity, bool>> predicate)
        {
            Repository.Delete(predicate);
        }

        public bool Contains(Expression<Func<TEntity, bool>> predicate)
        {
            return Repository.Contains(predicate);
        }

        public virtual TEntity Find(params object[] keys)
        {
            return Repository.Find(keys);
        }

        public virtual void Save(TEntity TObject)
        {
            this.Save(TObject, SaveActionEnum.Auto);
        }

        public void Save(TEntity t, SaveActionEnum action)
        {
            if (action == SaveActionEnum.Create)
            {
                Repository.Create(t);
            }
            else if (action == SaveActionEnum.Update)
            {
                Repository.Update(t);
            }
            else if (action == SaveActionEnum.Auto)
            {
                Repository.Save(t);
            }
        }

    }
}
